using System.Text;
using BPanel.Core.Middlewares;
using BPanel.Core.YidGenerator;
using BPanel.Database.Entities;
using FreeSql.Internal;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddControllersWithViews().AddJsonOptions(options => { options.JsonSerializerOptions.Converters.Add(new JsonDateTimeConverter("yyyy-MM-dd HH:mm:ss")); });
builder.Services.AddRazorPages().AddRazorRuntimeCompilation();
builder.Services.AddSwaggerGen(swgger =>
{
    //添加安全定义
    swgger.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Description = "请输入token,格式为 Bearer xxxxxxxx（注意中间必须有空格）",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey,
        BearerFormat = "JWT",
        Scheme = "Bearer"
    });
    //添加安全要求
    swgger.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            new string[] { }
        }
    });
});

var key = Encoding.ASCII.GetBytes(builder.Configuration.GetValue<string>("JwtSecurityKey") ?? string.Empty); // 替换为你的密钥
builder.Services.AddAuthentication(c =>
    {
        c.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        c.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    })
    .AddJwtBearer(c =>
    {
        c.RequireHttpsMetadata = false;
        c.SaveToken = true;
        c.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ValidateIssuer = false,
            ValidateAudience = false
        };
    });

builder.Services.AddYitterIdGenerator();

var connectionString = builder.Configuration.GetValue<string>("ConnectionStrings:SqlConnection");
Func<IServiceProvider, IFreeSql> freeSqlFactory = r =>
{
    var freeSql = new FreeSql.FreeSqlBuilder()
        .UseConnectionString(FreeSql.DataType.Sqlite, connectionString)
        .UseAutoSyncStructure(true) //自动同步实体结构到数据库，FreeSql不会扫描程序集，只有CRUD时才会生成表。
        .UseNameConvert(NameConvertType.PascalCaseToUnderscoreWithLower)
        .Build();
    return freeSql;
};
builder.Services.AddSingleton<IFreeSql>(freeSqlFactory);

builder.Services.Configure<ApiBehaviorOptions>(options =>
{
    // 禁用默认模型验证过滤器
    options.SuppressModelStateInvalidFilter = true;
});
builder.Services.Configure<MvcOptions>(options =>
{
    // 全局添加自定义模型验证过滤器
    options.Filters.Add<DataValidationFilter>();
});
builder.Services.AddRouting();

var app = builder.Build();

app.Use((context, next) =>
{
    var val = context.Request.Path.Value;
    if (string.IsNullOrWhiteSpace(val))
        val = "/";

    if (val == "/")
    {
    }
    else if (val.Contains("swagger"))
    {
    }
    else if (!val.StartsWith("/api/") && !val.Contains("index.html"))
    {
        // context.Request.Path = new PathString("/index.html#" + val);

        // var filename = Path.Combine(Path.GetDirectoryName(Path.Join(app.Environment.WebRootPath, context.Request.Path))!, "index.html");
        // context.Response.SendFileAsync(filename).ConfigureAwait(false);
    }

    next();
    return Task.CompletedTask;
});

//在项目启动时，从容器中获取IFreeSql实例，并执行一些操作：同步表，种子数据,FluentAPI等
using (var serviceScope = app.Services.CreateScope())
{
    var freeSql = serviceScope.ServiceProvider.GetRequiredService<IFreeSql>();
    freeSql.CodeFirst.SyncStructure(typeof(BPanel.Database.Entities.System));
    freeSql.CodeFirst.SyncStructure(typeof(Database));
    freeSql.CodeFirst.SyncStructure(typeof(WebSite));
    freeSql.CodeFirst.SyncStructure(typeof(WebSiteDomain));
    freeSql.CodeFirst.SyncStructure(typeof(WebSiteFtp));
    freeSql.CodeFirst.SyncStructure(typeof(PhpVersion));
}

// 注册中间件
app.UseMiddleware<UnifiedResponseMiddleware>();

// Configure the HTTP request pipeline.
// if (app.Environment.IsDevelopment())
// {
app.UseSwagger();
app.UseSwaggerUI();
//}
app.UseRouting();
app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();
app.MapFallbackToFile("/index.html");

app.Run();